#include "GridModel.h"
#include "Ruler.h"

namespace LeGraphicsView
{

    GridModel::GridModel(QObject *parent) :
        QObject(parent),
        m_horizontalRuler(new Ruler(this)),
        m_verticalRuler(new Ruler(this)),
        m_minimumSceneStep(0.1),
        m_minimumTickSpacing(10),
        m_coarseMultiplier(10),
        m_sceneRect(0, 0, 1.0, 1.0),
        m_size(100, 100)
    {
        m_horizontalRuler->setMinimumValueStep(m_minimumSceneStep);
        m_verticalRuler->setMinimumValueStep(m_minimumSceneStep);
        m_horizontalRuler->setMinimumTickSpacing(m_minimumTickSpacing);
        m_verticalRuler->setMinimumTickSpacing(m_minimumTickSpacing);
        m_horizontalRuler->setCoarseMultiplier(m_coarseMultiplier);
        m_verticalRuler->setCoarseMultiplier(m_coarseMultiplier);
        m_horizontalRuler->setMinimumValue(m_sceneRect.left());
        m_horizontalRuler->setMaximumValue(m_sceneRect.right());
        m_verticalRuler->setMinimumValue(m_sceneRect.top());
        m_verticalRuler->setMaximumValue(m_sceneRect.bottom());
        m_horizontalRuler->setSize(m_size.width());
        m_verticalRuler->setSize(m_size.height());
    }

    int GridModel::minimumTickSpacing() const
    {
        return m_minimumTickSpacing;
    }

    int GridModel::coarseMultiplier() const
    {
        return m_coarseMultiplier;
    }

    QSize GridModel::size() const
    {
        return m_size;
    }

    QVector<qreal> GridModel::majorXValues() const
    {
        return m_horizontalRuler->majorValues();
    }

    QVector<qreal> GridModel::minorXValues() const
    {
        return m_horizontalRuler->minorValues();
    }

    QVector<qreal> GridModel::majorYValues() const
    {
        return m_verticalRuler->majorValues();
    }

    QVector<qreal> GridModel::minorYValues() const
    {
        return m_verticalRuler->minorValues();
    }

    QVector<int> GridModel::majorXTicks() const
    {
        return m_horizontalRuler->majorTicks();
    }

    QVector<int> GridModel::minorXTicks() const
    {
        return m_horizontalRuler->minorTicks();
    }

    int GridModel::xTickPosition(qreal pos)
    {
        return m_horizontalRuler->tickPosition(pos);
    }

    QVector<int> GridModel::majorYTicks() const
    {
        return m_verticalRuler->majorTicks();
    }

    QVector<int> GridModel::minorYTicks() const
    {
        return m_verticalRuler->minorTicks();
    }

    int GridModel::yTickPosition(qreal pos)
    {
        return m_verticalRuler->tickPosition(pos);
    }

    QPointF GridModel::round(const QPointF &scenePos) const
    {
        return QPointF(m_horizontalRuler->roundValue(scenePos.x()),
                       m_verticalRuler->roundValue(scenePos.y()));
    }

    qreal GridModel::minimumSceneStep() const
    {
        return m_minimumSceneStep;
    }

    QRectF GridModel::sceneRect() const
    {
        return m_sceneRect;
    }

    void GridModel::setMinimumSceneStep(qreal step)
    {
        if (qFuzzyCompare(m_minimumSceneStep, step))
        {
            return;
        }

        m_minimumSceneStep = step;
        m_horizontalRuler->setMinimumValueStep(m_minimumSceneStep);
        m_verticalRuler->setMinimumValueStep(m_minimumSceneStep);
        emit minimumSceneStepChanged(m_minimumSceneStep);
    }

    void GridModel::setMinimumTickSpacing(int spacing)
    {
        if (m_minimumTickSpacing == spacing)
        {
            return;
        }

        m_minimumTickSpacing = spacing;
        m_horizontalRuler->setMinimumTickSpacing(m_minimumTickSpacing);
        m_verticalRuler->setMinimumTickSpacing(m_minimumTickSpacing);
        emit minimumTickSpacingChanged(m_minimumTickSpacing);
    }

    void GridModel::setCoarseMultiplier(int multiplier)
    {
        if (m_coarseMultiplier == multiplier)
        {
            return;
        }

        m_coarseMultiplier = multiplier;
        m_horizontalRuler->setCoarseMultiplier(m_coarseMultiplier);
        m_verticalRuler->setCoarseMultiplier(m_coarseMultiplier);
        emit coarseMultiplierChanged(m_coarseMultiplier);
    }

    void GridModel::setSceneRect(const QRectF &rect)
    {
        if (m_sceneRect == rect)
            return;

        m_sceneRect = rect;
        m_horizontalRuler->setMinimumValue(m_sceneRect.left());
        m_horizontalRuler->setMaximumValue(m_sceneRect.right());
        m_verticalRuler->setMinimumValue(m_sceneRect.top());
        m_verticalRuler->setMaximumValue(m_sceneRect.bottom());
        emit sceneRectChanged(m_sceneRect);
    }

    void GridModel::setSize(QSize size)
    {
        if (m_size == size)
            return;

        m_size = size;
        m_horizontalRuler->setSize(m_size.width());
        m_verticalRuler->setSize(m_size.height());
        emit sizeChanged(m_size);
    }

}
